<template>
	<div>
		<el-card :class="{ mt20: search != null }" shadow="never">
			<div class="search-panel" v-if="search">
				<slot name="search"></slot>
				<!-- 渲染搜索区域 -->
				<el-row :gutter="10" style="margin-top: -15px;">
					<el-col v-for="item in search" :key="item.label" :lg="item.span" :xs="item.span * 2" style=" margin-top: 15px;">
						<component :is="getComponent(item)" size="medium" :prefix-icon="item.icon" :count="item.count || 0"
							:placeholder="item.label" clearable v-model="item.value" style="width: 100%;">
							<el-option v-if="item.type === 'select'" v-for="option in item.data" :key="option.id"
								:label="option.name" :value="option.id"></el-option>
						</component>
					</el-col>
				</el-row>
				<el-row class="mt15">
					<el-col :lg="12" :xs="24">
						<el-button size="small" type="success" icon="el-icon-search" @click="onSearch">搜索</el-button>
						<el-button size="small" v-if="action.add" type="danger" icon="el-icon-circle-plus-outline"
							@click="beforEdit('add')">添加</el-button>
						<el-button size="small"  v-if="action.export" type="danger" icon="el-icon-circle-plus-outline"
							@click="showExportPanel = true">导出</el-button>

						<slot name="top"></slot>

					</el-col>
				</el-row>
			</div>

			<el-table border stripe :data="list" v-loading="loading" :header-cell-style="{ 'text-align': 'center' }"
				:show-summary="false" @selection-change="handleSelectionChange"
				:cell-style="{ 'text-align': 'center', 'font-size': '12px' }">

				<el-table-column type="index" width="70" labe="序号" />

				<el-table-column v-if="action.selected" type="selection" width="55"></el-table-column>

				<slot></slot>

				
				<el-table-column label="操作" :width="action.width || 180" v-if="action.remove || action.edit" fixed="right">
					<template slot-scope="row">
						<el-button style="margin-right: 20px;" v-if="action.edit" type="success" size="mini"
							@click="beforEdit('edit', row.row)">编辑</el-button>

						<el-popover placement="top" width="180" v-if="action.remove">
							<p>确认删除此条数据？</p>
							<div style="text-align: right; margin: 0">
								<el-button type="success" size="mini" @click="removeData(row.row)">确定</el-button>
							</div>

							<el-button type="danger" size="mini" slot="reference">删除</el-button>
						</el-popover>

					</template>
				</el-table-column>

			</el-table>

			<el-pagination  class="mt20" layout="prev, pager, next , total" background :total="total"
				:page-size="pagesize" :current-page="pageno" @current-change="pagechange"></el-pagination>

		</el-card>

		<el-drawer title="数据操作" :visible.sync="showEditPanel" size="550px" :destroy-on-close="true"
			:wrapperClosable="false">
			<el-form style="box-sizing: border-box; padding: 10px 20px;" label-position="top">
				<slot name="form"></slot>

				<el-form-item v-for="item in params" :label="item.label" v-if="!item.hide" label-width="150">
					
					<component style="width: 100%;" :url="item.url" :is="getFromComponet(item)" :count="item.count || 0"
						:placeholder="item.label" v-model="item.value" :type="item.type"
						value-format="yyyy-MM-dd HH:mm:ss" clearable>

						<el-option v-if="item.type === 'select'" v-for="option in item.data" :key="option.id"
							:label="option.name" :value="option.id"></el-option>

					</component>

					

				</el-form-item>

				<slot name="params"></slot>

				<el-button type="danger" size="medium" class="mt15" @click="submit">提交</el-button>
			</el-form>
		</el-drawer>

		<el-dialog title="导出数据" :visible.sync="showExportPanel" width="350px">
			<el-form style="box-sizing: border-box; padding: 10px 0;">
				<el-form-item label="导出页数">
					<el-input v-model="exportPageCount"></el-input>
				</el-form-item>
			</el-form>
			<template slot="footer">
				<el-button type="danger" class="mt15" @click="exportExcel">导出</el-button>
			</template>
		</el-dialog>

	</div>
</template>

<script>
const defaultUrl = { query: null, remove: null, edit: null, export: null, import: null }

const defaultAction = { selected: true, add: true, edit: true, remove: true, export: true, import: true }

import { Session } from '@/utils/storage'

import request from '@/utils/request'

export default {
	props: {
		params: {
			type: Array,
			default: () => []
		},
		action: {
			type: Object,
			default: () => defaultAction
		},
		pagesize: {
			type: Number,
			default: 10
		},
		name: {
			type: String,
			default: ''
		},
		urls: {
			type: Object,
			default: () => defaultUrl
		},
		search: {
			type: Array,
			default: () => []
		}
	},
	data() {
		return {
			//删除
			removeVisible: false,
			//导出页数
			exportPageCount: 1,
			//显示导出面板
			showExportPanel: false,
			//编辑面板显示
			showEditPanel: false,
			//总数据
			total: 0,
			//加载
			loading: true,
			//数据
			list: [],
			//当前页码
			pageno: 1,
			//操作类型 add添加数据 edit编辑数据
			editType: 'add',
			//上传地址
			uploadUrl: '',
			//上传文件请求头
			uploadHeaders: {}
		}
	},
	mounted() {

		this.load()

		this.uploadUrl = `${request.defaults.baseURL}${this.urls.import}`

		this.uploadHeaders = { 'Authorization': `Bearer ${Session.get('token')}` }

	},
	computed: {
		showSum() {
			return this.sumMethod != null
		}
	},
	methods: {
		//重新加载数据
		reload() {
			this.load()
		},
		//分页发生变化
		pagechange(e) {
			this.pageno = e
			this.load()
		},
		//加载数据
		async load() {
			let url = this.getUrl('page')

			this.loading = true

			let searchStr = encodeURIComponent(JSON.stringify(this.search))

			const res = await request({
				method: 'get',
				url: url,
				headers: {
					pageno: this.pageno,
					pagesize: this.pagesize,
					search: searchStr
				}
			})

			if (!res.items) {
				this.list = res
				this.total = res.length

			} else {
				this.list = res.items
				this.total = res.totalCount
			}

			this.loading = false
		},
		//搜索按钮点击
		onSearch() {
			this.pageno = 1
			this.load()
		},
		//清空搜索
		clearSerach() {
			Object.keys(this.search).forEach(key => {
				if (typeof this.search[key] === 'object' && this.search[key] !== null && 'value' in this.search[key]) {
					this.search[key].value = '';
				}
			});
		},
		//清空表单内容
		clearParams() {

			this.params.forEach((item, index) => {
				item.value = null
				this.$set(this.params, index, item)
			})
		},
		//编辑前的预处理
		beforEdit(type, e) {

			this.clearParams()

			this.showEditPanel = true

			this.editType = type

			if (e) {

				let result = this.dataToParams(e)

				this.$emit('update:params', result)
			}
			else {


				let index = this.params.findIndex(x => x.name == 'id')

				this.params[index].value = 0

				this.$emit('update:params', this.params)
			}

		},
		//参数转真实数据
		paramsToData() {
			let result = {}
			this.params.forEach(item => {
				result[item.name] = item.value
			})
			return result
		},
		//数据转真实参数
		dataToParams(obj) {
			let result = []
			Object.keys(obj).forEach(key => {
				let index = this.params.findIndex(x => x.name == key)
				if (index > -1) {
					let data = this.params[index]
					data.value = obj[key]
					result.push(data)
				}
			})
			return result
		},
		//真实的编辑添加数据提交
		async submit() {

			let url = this.getUrl('edit')

			const res = await request.post(url, this.paramsToData())

			this.showEditPanel = false

			this.clearParams()

			this.$message.success('编辑成功')

			this.reload()

		},
		//删除数据
		async removeData(e) {

			let url = this.getUrl('remove')

			const res = await request.delete(`${url}/${e.id}`)

			this.$message.success('删除成功')

			this.reload()
		},
		//导出数据
		async exportExcel() {

			let url = this.getUrl('export')

			let searchStr = encodeURIComponent(JSON.stringify(this.search))

			const res = await request(
				{
					method: 'post',
					url: url,
					data: this.exportPageCount,
					responseType: 'blob',
					headers:
					{
						search: searchStr,
						pageno: this.pageno,
						pagesize: this.pagesize
					}
				})

			const a = document.createElement('a');

			a.href = URL.createObjectURL(res);

			// 设置下载文件名
			a.setAttribute('download', 'demo.xlsx');

			document.body.appendChild(a);

			a.click();

			document.body.removeChild(a);

			this.$message.success('导出成功')
		},
		handleSelectionChange(e) {
			this.$emit('onSelect', e)
		},
		beforImport() {

		},
		getComponent(item) {
			//输入
			if (item.type === 'like' || item.type === 'text') return 'el-input'
			//选择
			if (item.type === 'select') return 'el-select'

		},
		getFromComponet(item) {
			if (item.type === 'number' || item.type === 'string' || item.type === 'textarea') return 'el-input'

			if (item.type === 'select') return 'el-select';

			if (item.type === 'bool') return 'el-switch'

			if (item.type === 'image') return 'm-upload'

			if (item.type === 'video') return 'm-upload'

			if (item.type === 'apiSelect') return 'apiSelect'

			if (item.type === 'date' || item.type === 'datetime') return 'el-date-picker'
		},
		getUrl(name) {
			if (!this.urls && !this.urls[name] && !this.name) {
				alert(`未配置${name}`)
			}

			if (this.name && this.name.length > 0) {
				return name == 'remove' ? this.name : `${this.name}/${name}`
			}

			if (this.urls[name] && this.urls[name].length > 0) {
				return this.urls[name]
			}
		}

	}
}
</script>

<style lang="scss" scoped>

.search-panel{
	margin-bottom: 40px;
}

</style>
